﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using personalplaner.common.mvvm;
using personalplaner.business.stamm;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using personalplaner.gui.stamm.views;
using System.Windows.Input;
using personalplaner.common.mvvm.commands;
using personalplaner.gui.stamm.viewmodels.models;
using System.Windows;

namespace personalplaner.gui.common.viewmodels.models
{
	public class InitWizardPersonModel : BaseModel
	{
		public InitWizardPersonModel()
		{
			InitializePerson();
		}

		#region Implementation

		private void InitializePerson()
		{
            AdditionalInfoModel = new PersonAdditionalInfoModel();
            PersonAbteilungModel = new PersonAbteilungModel();

			AdditionalInfoModel.Von = DateTime.Now;
			AdditionalInfoModel.Bis = DateTime.Now.AddYears(20);

			SelectedPerson = new Person();

		}

		#endregion

		#region Commands

        #region Wizard

        ICommand _okcommand;
		public ICommand OkCommand
		{
			get
			{
				if (_okcommand == null)
					_okcommand = new RelayCommand(OnOkCommand, CanExecuteOk);
				return _okcommand;
			}
		}

		private void OnOkCommand(object parameter)
		{
			Personen.Add(SelectedPerson);
            AdditionalInfos.Add(SelectedPerson, AdditionalInfoModel);
            PersonAbteilungen.Add(SelectedPerson, PersonAbteilungModel);

            InitializePerson();

            SelectedView = Views[0];
            SelectedView.DataContext = SelectedPerson;
		}

		private bool CanExecuteOk(object parameter)
		{
			RaisePropertyChanged("IsEndOfWizard");
			return IsEndOfWizard && PersonAbteilungModel.AbteilungenZugeteilt.Count > 0;
		}

		ICommand _nextcommand;
		public ICommand NextCommand
		{
			get
			{
				if (_nextcommand == null)
					_nextcommand = new RelayCommand(OnNext, parameter => SelectedView != Views[2]);
				return _nextcommand;
			}
		}

		private void OnNext(object parameter)
		{
			if (IsEndOfWizard)
				return;

			if (SelectedView is PersonalienView)
			{
				if (!SelectedPerson.IsValid)
					return;
			}
			else if (SelectedView is PersonAdditionalInfoView)
			{

			}
			else if (SelectedView is PersonaAbteilungView)
			{
			}


			for (int i = 0; i < Views.Count; i++)
			{
				if (Views[i] == SelectedView)
				{
					SelectedView = Views[i + 1];
					break;
				}
			}


			if (SelectedView is PersonalienView)
			{
			}
			else if (SelectedView is PersonAdditionalInfoView)
			{
			}
			else if (SelectedView is PersonaAbteilungView)
			{
				PersonAbteilungModel.MaxPensum = AdditionalInfoModel.Pensum;
				PersonAbteilungModel.Pensum = PersonAbteilungModel.MaxPensum;

				PersonAbteilungModel.Von = AdditionalInfoModel.Von;
				PersonAbteilungModel.Bis = AdditionalInfoModel.Bis;

				PersonAbteilungModel.AbteilungenZugeteilt.Clear();
				PersonAbteilungModel.AbteilungenNichtZugeteilt.Clear();

				foreach (var itm in Abteilungen)
					PersonAbteilungModel.AbteilungenNichtZugeteilt.Add(new PersonAbteilung
					{
						AbteilungID = itm.AbteilungID,
						Name = itm.Name,
						Beschreibung = itm.Beschreibung,
						EinsaetzeProTag = itm.EinsaetzeProTag
					});
			}
		}

		ICommand _previouscommand;
		public ICommand PreviousCommand
		{
			get
			{
				if (_previouscommand == null)
					_previouscommand = new RelayCommand(OnPrevious, parameter => SelectedView != Views[0]);
				return _previouscommand;
			}
		}

		private void OnPrevious(object parameter)
		{
			for (int i = 0; i < Views.Count; i++)
			{
				if (Views[i] == SelectedView)
				{
					SelectedView = Views[i - 1];
					break;
				}
			}
		}

        #endregion

        #region Abteilung

        ICommand _addToListCommand;
        public ICommand AddToListCommand
        {
            get
            {
                if (_addToListCommand == null)
                    _addToListCommand = new RelayCommand(OnAddToList, parameter => PersonAbteilungModel.SelectedAbteilungNichtZugeteilt != null);
                return _addToListCommand;
            }
        }

        private void OnAddToList(object parameter)
        {
            if (PersonAbteilungModel.SelectedAbteilungNichtZugeteilt == null)
                return;

            if (PersonAbteilungModel.Pensum <= 0)
            {
                MessageBox.Show("Es wurde kein Pensum-Prozentsatz ausgewählt.\nBitte geben Sie ein Prozentsatz ein.", "Kein Prozentsatz", MessageBoxButton.OK);
                PersonAbteilungModel.RaiseMoveFocus("Pensum");
                return;
            }

            if (PersonAbteilungModel.IsValid)
            {
                if (PersonAbteilungModel.Von < PersonAbteilungModel.Bis)
                {
                    var abteilung = PersonAbteilungModel.SelectedAbteilungNichtZugeteilt;

                    PersonAbteilungModel.AbteilungenZugeteilt.Add(abteilung);
                    PersonAbteilungModel.AbteilungenNichtZugeteilt.Remove(abteilung);

                    abteilung.Von = PersonAbteilungModel.Von;
                    abteilung.Bis = PersonAbteilungModel.Bis;
                    abteilung.Prozent = PersonAbteilungModel.Pensum;

                    PersonAbteilungModel.Pensum = 0;

                    RefreshPensumData();
                }
            }
            else
            {
                MessageBox.Show("Ungültiger Pensum-Prozentsatz.\nBitte wälhlen Sie einen Prozentsatz zwischen 0 und " + PersonAbteilungModel.MaxPensum + " aus", "Ungültiger Prozentsatz", MessageBoxButton.OK);
                PersonAbteilungModel.RaiseMoveFocus("Pensum");
            }
        }

        ICommand _removeFromListCommand;
        public ICommand RemoveFromListCommand
        {
            get
            {
                if (_removeFromListCommand == null)
                    _removeFromListCommand = new RelayCommand(OnRemoveFromList, parameter => PersonAbteilungModel.SelectedAbteilungZugeteilt != null);
                return _removeFromListCommand;
            }
        }

        private void OnRemoveFromList(object parameter)
        {
            if (PersonAbteilungModel.SelectedAbteilungZugeteilt == null)
                return;

            var abteilung = PersonAbteilungModel.SelectedAbteilungZugeteilt;
            PersonAbteilungModel.AbteilungenZugeteilt.Remove(abteilung);
            PersonAbteilungModel.AbteilungenNichtZugeteilt.Add(abteilung);

            PersonAbteilungModel.Pensum = 0;

            RefreshPensumData();
        }

        private void RefreshPensumData()
        {
            var pens = AdditionalInfoModel.Pensum;

            foreach (var itm in PersonAbteilungModel.AbteilungenZugeteilt)
                pens -= itm.Prozent;
            PersonAbteilungModel.MaxPensum = pens;
        }

        #endregion

		#endregion

		#region Properties

		IList<Person> _personen;
		public IList<Person> Personen
		{
			get
			{
				if (_personen == null)
					_personen = new ObservableCollection<Person>();
				return _personen;
			}
		}

        Dictionary<Person, PersonAdditionalInfoModel> _additionalInfos;
        public Dictionary<Person, PersonAdditionalInfoModel> AdditionalInfos
        {
            get
            {
                if (_additionalInfos == null)
                    _additionalInfos = new Dictionary<Person, PersonAdditionalInfoModel>();
                return _additionalInfos;
            }
        }

        Dictionary<Person, PersonAbteilungModel> _personAbteilungen;
        public Dictionary<Person, PersonAbteilungModel> PersonAbteilungen
        {
            get
            {
                if (_personAbteilungen == null)
                    _personAbteilungen = new Dictionary<Person, PersonAbteilungModel>();
                return _personAbteilungen;
            }
        }

		Person _activegriditem;
		public Person ActiveGridItem
		{
			get
			{
				return _activegriditem;
			}
			set
			{
				_activegriditem = value;
				RaisePropertyChanged("ActiveGridItem");

				SelectedPerson = value;
			}
		}

		Person _selectedPerson;
		public Person SelectedPerson
		{
			get
			{
				if (_selectedPerson == null)
					_selectedPerson = new Person();
				return _selectedPerson;
			}
			set
			{
				_selectedPerson = value;
				RaisePropertyChanged("SelectedPerson");
				RaisePropertyChanged("IsEditEnabled");
			}
		}

		#region Wizard

		IList<UserControl> _views;
		public IList<UserControl> Views
		{
			get
			{
				if (_views == null)
				{
					_views = new List<UserControl>
					         {
					         	new PersonalienView
					         	{
					         		DataContext = SelectedPerson,
					         		BorderThickness = new Thickness(0)
					         	},
					         	new PersonAdditionalInfoView(),
					         	new PersonaAbteilungView()
					         };
				}
				return _views;
			}
		}

		UserControl _selectedView;
		public UserControl SelectedView
		{
			get
			{
				if (_selectedView == null)
					_selectedView = Views[0];
				return _selectedView;
			}
			set
			{
				_selectedView = value;
				RaisePropertyChanged("SelectedView");
			}
		}

		public bool IsEndOfWizard
		{
			get
			{
				return SelectedView == Views[2];
			}
		}

		#endregion

		#region Additional info

		PersonAdditionalInfoModel _personaadditionalinfomodel;
		public PersonAdditionalInfoModel AdditionalInfoModel
		{
			get
			{
				if (_personaadditionalinfomodel == null)
					_personaadditionalinfomodel = new PersonAdditionalInfoModel();
				return _personaadditionalinfomodel;
            }
            set
            {
                _personaadditionalinfomodel = value;
                RaisePropertyChanged("AdditionalInfoModel");
            }
		}

		IList<Anstellung> _anstellungen;
		public IList<Anstellung> Anstellungen
		{
			get
			{
				if (_anstellungen == null)
					_anstellungen = new ObservableCollection<Anstellung>();
				return _anstellungen;
			}
			set
			{
				_anstellungen = value;
				RaisePropertyChanged("Anstellungen");
			}
		}
		
		#region Abteilung

		PersonAbteilungModel _personabteilungmodel;
		public PersonAbteilungModel PersonAbteilungModel
		{
			get
			{
				if (_personabteilungmodel == null)
					_personabteilungmodel = new PersonAbteilungModel();
				return _personabteilungmodel;
            }
            set
            {
                _personabteilungmodel = value;
                RaisePropertyChanged("PersonAbteilungModel");
            }
		}

		IList<Abteilung> _abteilungen;
		public IList<Abteilung> Abteilungen
		{
			get
			{
				if (_abteilungen == null)
					_abteilungen = new ObservableCollection<Abteilung>();
				return _abteilungen;
			}
			set
			{
				_abteilungen = value;
				RaisePropertyChanged("Abteilungen");
			}
		}

		#endregion

		#endregion

		#endregion
	}
}
